/*实现项目中的功能代码
 日志宏定义
 Json的序列化与反序列化
 uuid的生成
*/
#pragma once
#include<cstdio>
#include<ctime>
#include<iostream>
#include<string>
#include<memory>
#include<random>
#include<sstream>
#include<atomic>
#include<iomanip>
#include<jsoncpp/json/json.h>

namespace RpcMacro
{
    #define LDBG 0 
    #define LINF 1
    #define LERR 2

    #define LEDFAULT LDBG //默认

    //日志消息
    #define LOG(level,format,...) \
    {                             \
        if(level>=LEDFAULT)       \
            {                     \
                time_t t = time(NULL); \
                struct tm *st = localtime(&t);\
                char time_str[32] = {0};      \
                strftime(time_str,31,"%m-%d %T",st);\
                fprintf(stdout,"[%s][%s:%d]" format "\n",time_str,__FILE__,__LINE__,##__VA_ARGS__);\
            }\
    }
    #define DLOG(format,...)LOG(LDBG,format,##__VA_ARGS__);
    #define ILOG(format,...)LOG(LINF,format,##__VA_ARGS__);
    #define ELOG(format,...)LOG(LERR,format,##__VA_ARGS__);

   //json序列化
   class JSON
   {
        public:
        static bool serialize(const Json::Value &val,std::string &body)//
        {
            std::stringstream sm;
            //实例化工厂
            Json::StreamWriterBuilder swb;
            //工厂类对象来生产派生类对象
            swb.settings_["emitUTF8"] = true;
            std::unique_ptr<Json::StreamWriter>sw(swb.newStreamWriter());
            int ret = sw->write(val,&sm);
            if(ret!=0)
            {
                ELOG("Jsos");
                return false;
            }
            body==sm.str();
            return true;
        }
       static  bool unserialize(const std::string &body, Json::Value &val)
        {
            Json::CharReaderBuilder crb;
            std::string errs;
            // Charreader 将Json字符串解析为Json::value 对象 负责字符级别的Json解析，
            // nwecharreader()会创建一个charReader实列并返回其裸指针；
            std::unique_ptr<Json::CharReader> cr(crb.newCharReader());
            bool ret = cr->parse(body.c_str(), body.c_str() + body.size(), &val, &errs);
            if (ret == false)
            {
                 ELOG("json unserialize failed:%s",errs.c_str());
                return false; // 反序列化失败
            }
            return true;
        }
   };
   

   class UUID
   {
       public:
        static std::string uuid()
        {
            //用于对字符串进行流式输入/输出操作,但操作对象是内存中的字符串
            //将各种数据类型转换为字符串
            std::stringstream sm;
            //1:构造一个机器随机数对象
            std::random_device rd;
            //2.以机器随机数为种子构造伪随机数对象
            std::mt19937 generator(rd());
            //3.构造限定数据返回的对象
            std::uniform_int_distribution<int> disreibution(0,255);
            //4.生成8和随机数，按照特定格式组织为15进制数字字符串的字符
            for(int i = 0;i<8;i++)
            {
               if(i==4||i==6)
               {
                    sm<<"-";
               }
               sm<<std::setw(2)<<std::setfill('0')<<std::hex<<disreibution(generator);
            }
            sm<<"-";
            //定义8字节序号，字节组织称为16进制数字字符的字符串
            static std::atomic<size_t>seq(1);//00 00 00 00 00 00 00 01
            size_t cur = seq.fetch_add(1);
            for(int i =7;i>=0;i--)
            {
                if(i==5)
                {
                    sm<<"-";
                }
                sm<<std::setw(2)<<std::setfill('0')<<std::hex<<((cur>>(i*8))&0xFF);
            }
            return sm.str();
        }
   };

}

   